home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 August: Tool Chest / Dev.CD Aug 98 TC.toast / Sample Code / Text / SimpleText Sample / PICTFile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-17  |  21.2 KB  |  766 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        PICTFile.c
  3.  
  4.     Contains:    PICT file for simple text application
  5.  
  6.     Version:    SimpleText 1.4 or later
  7.  
  8. ** Copyright 1993-1996 Apple Computer. All rights reserved.
  9. **
  10. **    You may incorporate this sample code into your applications without
  11. **    restriction, though the sample code has been provided "AS IS" and the
  12. **    responsibility for its operation is 100% yours.  However, what you are
  13. **    not permitted to do is to redistribute the source as "DSC Sample Code"
  14. **    after having made changes. If you're going to re-distribute the source,
  15. **    we require that you make it clear in the source that the code was
  16. **    descended from Apple Sample Code, but that you've made changes.
  17.  
  18. */
  19.  
  20. #include "MacIncludes.h"
  21.  
  22. #include "PICTFile.h"
  23.  
  24. /* ------------------------------------------------------------------------------------    */
  25. /* GLOBALS ONLY USED BY THIS FILE */
  26. /* ------------------------------------------------------------------------------------    */
  27. #define kBufferSize    2048
  28.  
  29. static short            gPictFileRefNum;
  30. static char                gPictureBuffer[kBufferSize];
  31. static long                gAmountInBuffer;
  32. static long                gFirstCharInBuffer;
  33. static QDProcsPtr         gSavedProcs;
  34. static QDProcs            gMyProcs;
  35. static CQDProcs           gMyColorProcs;
  36.  
  37. // --------------------------------------------------------------------------------------------------------------
  38. // INTERNAL ROUTINES
  39. // --------------------------------------------------------------------------------------------------------------
  40.  
  41. static pascal void GetPICTData(Ptr dataPtr,short byteCount)
  42. /*
  43.     replacement for the QuickDraw bottleneck routine
  44. */
  45.     OSErr            err = noErr;
  46.     long            longCount;
  47.  
  48.     longCount = byteCount;
  49.     
  50.     while ( (longCount > 0) && (err == noErr) )
  51.         {
  52.         if (gAmountInBuffer == 0)
  53.             {
  54.             gAmountInBuffer = kBufferSize;
  55.             gFirstCharInBuffer = 0;
  56.             err = FSRead(gPictFileRefNum,&gAmountInBuffer,gPictureBuffer);
  57.             }
  58.  
  59.         if (gAmountInBuffer > 0)
  60.             {
  61.             long    amountToMove;
  62.             
  63.             amountToMove = gAmountInBuffer;
  64.             if (amountToMove > longCount)
  65.                 amountToMove = longCount;
  66.                 
  67.             BlockMoveData(&gPictureBuffer[gFirstCharInBuffer], dataPtr, amountToMove);
  68.             longCount -= amountToMove;
  69.             dataPtr += amountToMove;
  70.             gFirstCharInBuffer += amountToMove;
  71.             gAmountInBuffer -= amountToMove;
  72.             }
  73.             
  74.         }
  75.     
  76. } // GetPICTData
  77.  
  78. #if GENERATINGCFM
  79.     static RoutineDescriptor gGetPICTDataRD = BUILD_ROUTINE_DESCRIPTOR(uppQDGetPicProcInfo, GetPICTData);
  80.     static QDGetPicUPP gGetPICTData = &gGetPICTDataRD;
  81. #else
  82.     static QDGetPicUPP gGetPICTData = NewQDGetPicProc(GetPICTData);
  83. #endif
  84.  
  85. // --------------------------------------------------------------------------------------------------------------
  86.  
  87. static OSErr    DiskPictureDraw( WindowDataPtr pData, 
  88.     Boolean doDraw, Rect *pictureRect, Point *pOffset)
  89. {
  90.  
  91.     OSErr        anErr;
  92.     PicHandle    picHandle;
  93.     Point        offset;
  94.     
  95.     if (pOffset)
  96.         offset = *pOffset;
  97.     else
  98.         {
  99.         offset.h = GetControlValue(pData->hScroll);
  100.         offset.v = GetControlValue(pData->vScroll);
  101.         }
  102.  
  103.     picHandle = ((PICTDataPtr)pData)->cacheHandle;
  104.     
  105.     if (picHandle)
  106.         {
  107.  
  108.  
  109.         if (doDraw)
  110.             {
  111.             Rect    destRect;
  112.             
  113.             GetPICTRectangleAt72dpi(picHandle, &destRect);
  114.  
  115.             OffsetRect(&destRect, 
  116.                                 -destRect.left + 
  117.                                     pData->contentRect.left -
  118.                                     offset.h, 
  119.                                 -destRect.top + 
  120.                                     pData->contentRect.top -
  121.                                     offset.v);
  122.             DrawPicture(picHandle, &destRect);
  123.             }
  124.         
  125.         if (pictureRect)
  126.             {
  127.             GetPICTRectangleAt72dpi(picHandle, pictureRect);
  128.             OffsetRect(pictureRect, -pictureRect->left, -pictureRect->top);
  129.             }
  130.             
  131.         picHandle = nil;
  132.         anErr = noErr;
  133.         }
  134.     else
  135.         {
  136.         // make enough room for PICT header, including version
  137.         picHandle = (PicHandle) NewHandle(sizeof(Picture)  + sizeof(long)*8);
  138.         anErr = MemError();
  139.         nrequire(anErr, FailedNewHandle);
  140.         
  141.         gPictFileRefNum = pData->dataRefNum;
  142.         anErr = SetFPos(gPictFileRefNum, fsFromStart, 512);
  143.         nrequire(anErr, FailedSetFPos);
  144.         
  145.         gAmountInBuffer = kBufferSize;
  146.         gFirstCharInBuffer = 0;
  147.         anErr = FSRead(gPictFileRefNum, &gAmountInBuffer, gPictureBuffer);
  148.         if (anErr == eofErr)
  149.             anErr = noErr;
  150.         if (gAmountInBuffer < sizeof(Picture))
  151.             anErr = eofErr;
  152.         nrequire(anErr, FailedInitialRead);
  153.     
  154.         // copy PICT header, including version
  155.         BlockMoveData(gPictureBuffer, *picHandle, sizeof(Picture) + sizeof(long)*8);
  156.         gFirstCharInBuffer += sizeof(Picture);
  157.         gAmountInBuffer -= sizeof(Picture);
  158.         
  159.         if (doDraw)
  160.             {
  161.             Rect    destRect;
  162.             
  163.             GetPICTRectangleAt72dpi(picHandle, &destRect);
  164.             if (!gMachineInfo.haveQuickTime)
  165.                 {
  166.                 if (gMachineInfo.theEnvirons.hasColorQD)
  167.                     {
  168.                     if ((*qd.thePort).grafProcs)
  169.                         BlockMoveData((*qd.thePort).grafProcs, &gMyColorProcs, sizeof(gMyColorProcs));
  170.                     else
  171.                         SetStdCProcs(&gMyColorProcs);
  172.                     }
  173.                 else
  174.                     {
  175.                     if ((*qd.thePort).grafProcs)
  176.                         BlockMoveData((*qd.thePort).grafProcs, &gMyProcs, sizeof(gMyProcs));
  177.                     else
  178.                         SetStdProcs(&gMyProcs);
  179.                     }
  180.                     
  181.                 gMyProcs.getPicProc = gGetPICTData;
  182.                 gMyColorProcs.getPicProc = gGetPICTData;
  183.                 gSavedProcs = (*qd.thePort).grafProcs;
  184.             
  185.                 if (gMachineInfo.theEnvirons.hasColorQD)
  186.                     (*qd.thePort).grafProcs = (QDProcsPtr)&gMyColorProcs;
  187.                 else
  188.                     (*qd.thePort).grafProcs = &gMyProcs;
  189.                 }
  190.                 
  191.             OffsetRect(&destRect, 
  192.                                 -destRect.left + 
  193.                                     pData->contentRect.left -
  194.                                     offset.h, 
  195.                                 -destRect.top + 
  196.                                     pData->contentRect.top -
  197.                                     offset.v);
  198.                                                 
  199.             if (!gMachineInfo.haveQuickTime)
  200.                 {
  201.                 DrawPicture(picHandle, &destRect);
  202.                 (*qd.thePort).grafProcs = gSavedProcs;
  203.                 }
  204.             else
  205.                 DrawPictureFile(gPictFileRefNum, &destRect, nil);
  206.     
  207.             }
  208.             
  209.         if (pictureRect)
  210.             {
  211.             GetPICTRectangleAt72dpi(picHandle, pictureRect);
  212.             OffsetRect(pictureRect, -pictureRect->left, -pictureRect->top);
  213.             }
  214.         }
  215.     
  216. // FALL THROUGH EXCEPTION HANDLING
  217. FailedInitialRead:
  218. FailedSetFPos:
  219.     DisposeHandle((Handle) picHandle);
  220.  
  221. FailedNewHandle:
  222.     
  223.     return(anErr);
  224.         
  225. } // DiskPictureDraw
  226.  
  227. // --------------------------------------------------------------------------------------------------------------
  228. static OSErr GetSelectedPicture(WindowDataPtr pData, PicHandle *pResult)
  229. {
  230.     OSErr        anErr;
  231.     PicHandle    scrapPict;
  232.     Rect        globRect;
  233.     GDHandle    theMaxDevice;
  234.     short        theDepth;
  235.     GDHandle    savedGDevice;
  236.     CGrafPtr    savedPort;
  237.     GWorldPtr    offscreenGWorld;
  238.  
  239.     // save away current value for restores
  240.     GetGWorld(&savedPort, &savedGDevice);
  241.  
  242.     // determine the best way in which to allocate stuff
  243.     
  244.     SetRect(&globRect, -32760, -32760, 32760, 32760);
  245.     theDepth = 1;
  246.     if (gMachineInfo.theEnvirons.hasColorQD)
  247.         {
  248.         theDepth = 8;
  249.         theMaxDevice = GetMaxDevice(&globRect);
  250.         if (theMaxDevice != nil)
  251.             theDepth = (**(**theMaxDevice).gdPMap).pixelSize;
  252.         }
  253.     
  254.     // allocate the GWorld in temp mem, or local if we run out
  255.     anErr = NewGWorld(&offscreenGWorld, theDepth, 
  256.                         &((PICTDataPtr)pData)->selectionRectangle,
  257.                         nil, nil, useTempMem);
  258.     if (anErr != noErr)
  259.         anErr = NewGWorld(&offscreenGWorld, theDepth, 
  260.                             &((PICTDataPtr)pData)->selectionRectangle,
  261.                             nil, nil, 0);
  262.     nrequire(anErr, FailedNewGWorld);
  263.  
  264.     // blow open the visRgn, and clip to the selected area
  265.     RectRgn(offscreenGWorld->visRgn, &globRect);
  266.     PortChanged((GrafPtr) offscreenGWorld);
  267.     SetGWorld(offscreenGWorld, nil);
  268.     EraseRect(&offscreenGWorld->portRect);
  269.     ClipRect(&((PICTDataPtr)pData)->selectionRectangle);
  270.     
  271.     // Draw the picture into the offscreen
  272.     LockPixels( GetGWorldPixMap(offscreenGWorld));
  273.     {
  274.     Point    offset = {0,0};
  275.     anErr = DiskPictureDraw(pData, true, false, &offset);
  276.     }
  277.     UnlockPixels( GetGWorldPixMap(offscreenGWorld));
  278.     nrequire(anErr, FailedDraw);
  279.  
  280.     // CopyBits in place to grab the selection
  281.     scrapPict = OpenPicture(&((PICTDataPtr)pData)->selectionRectangle);
  282.     LockPixels( GetGWorldPixMap(offscreenGWorld));
  283.     CopyBits(&((GrafPtr)offscreenGWorld)->portBits, &((GrafPtr)offscreenGWorld)->portBits, 
  284.         &((PICTDataPtr)pData)->selectionRectangle, &((PICTDataPtr)pData)->selectionRectangle,
  285.         srcCopy, nil);
  286.     anErr = QDError();
  287.     UnlockPixels( GetGWorldPixMap(offscreenGWorld));
  288.     ClosePicture();
  289.     globRect = (**scrapPict).picFrame;
  290.     if ( (anErr == noErr) && (EmptyRect(&globRect)) )
  291.         anErr = memFullErr;
  292.         
  293.     // done with our offscreen now
  294.     SetGWorld(savedPort, savedGDevice);
  295.     DisposeGWorld(offscreenGWorld);
  296.  
  297.     if (anErr == noErr)
  298.         *pResult = scrapPict;
  299.     
  300.     return(anErr);
  301.     
  302. // EXCEPTION HANDLING
  303. FailedDraw:
  304.     DisposeGWorld(offscreenGWorld);
  305.     
  306. FailedNewGWorld:
  307.  
  308.     SetGWorld(savedPort, savedGDevice);
  309.     return(anErr);
  310.     
  311. } // GetSelectedPicture
  312.  
  313. // --------------------------------------------------------------------------------------------------------------
  314. static OSErr CopyGWorld(WindowDataPtr pData)
  315. {
  316.     OSErr        anErr;
  317.     PicHandle    scrapPict;
  318.  
  319.     anErr = GetSelectedPicture(pData, &scrapPict);
  320.  
  321.     if (anErr == noErr)
  322.         {
  323.         if (LoadScrap() == noErr)
  324.             {
  325.             ZeroScrap();
  326.             HLock((Handle) scrapPict);
  327.             anErr = PutScrap(GetHandleSize((Handle) scrapPict), 'PICT', (Ptr)*scrapPict);
  328.             KillPicture(scrapPict);
  329.             }
  330.         }
  331.     
  332.     return(anErr);
  333.     
  334. } // CopyGWorld
  335.  
  336. // --------------------------------------------------------------------------------------------------------------
  337. static pascal OSErr PICTSendDataProc(FlavorType theType, void *dragSendRefCon,
  338.                                 ItemReference theItem, DragReference theDrag)
  339. /*
  340.  *    The ItemReference is the gxShape to be sent. The dragSendRefCon is ignored.
  341. */
  342. {
  343. #pragma unused (dragSendRefCon)
  344.  
  345.     OSErr    result = noErr;
  346.  
  347.     switch (theType) 
  348.         {
  349.         case 'PICT':
  350.             {    
  351.             PicHandle     pict;
  352.             OSErr        anErr = GetSelectedPicture((WindowDataPtr)theItem, &pict);
  353.     
  354.             if (anErr == noErr)
  355.                 {    
  356.                 HLock((Handle)pict);
  357.                 result = SetDragItemFlavorData(theDrag, theItem, 'PICT', (Ptr)*pict, GetHandleSize((Handle)pict), 0);
  358.                 KillPicture(pict);
  359.                 }
  360.             }
  361.             break;
  362.             
  363.         default:
  364.             result = badDragFlavorErr;
  365.             break;
  366.         }
  367.         
  368.     return result;
  369.     
  370. } // PICTSendDataProc
  371.  
  372.  
  373. #if GENERATINGCFM
  374.     static RoutineDescriptor gPICTSendDataProcRD = BUILD_ROUTINE_DESCRIPTOR(uppDragSendDataProcInfo, PICTSendDataProc);
  375.     static DragSendDataUPP gPICTSendDataProc = &gPICTSendDataProcRD;
  376. #else
  377.     static DragSendDataUPP gPICTSendDataProc = NewDragSendDataProc(PICTSendDataProc);
  378. #endif
  379.  
  380. // --------------------------------------------------------------------------------------------------------------
  381. // OOP INTERFACE ROUTINES
  382. // --------------------------------------------------------------------------------------------------------------
  383.  
  384. static OSErr    PICTUpdateWindow(WindowRef pWindow, WindowDataPtr pData)
  385. {
  386.     OSErr        anErr;
  387.     RgnHandle    oldClip = NewRgn();
  388.     
  389.     EraseRect(&pData->contentRect);
  390.     
  391.     GetClip(oldClip);
  392.     ClipRect(&pData->contentRect);
  393.     anErr = DiskPictureDraw( pData, true, nil, nil);
  394.     SetClip(oldClip);
  395.     DisposeRgn(oldClip);
  396.     
  397.     DrawSelection(pData, &((PICTDataPtr)pData)->selectionRectangle, &((PICTDataPtr)pData)->patternPhase, false);
  398.     
  399.     DrawControls(pWindow);
  400.     DrawGrowIcon(pWindow);
  401.     
  402.     return(anErr);
  403.     
  404. } // PICTUpdateWindow
  405.  
  406. // --------------------------------------------------------------------------------------------------------------
  407.  
  408. static OSErr    PICTGetDocumentRect(WindowRef pWindow, WindowDataPtr pData, 
  409.             LongRect * documentRectangle, Boolean forGrow)
  410. {
  411. #pragma unused (pWindow, forGrow)
  412.  
  413.     RectToLongRect(&((PICTDataPtr)pData)->pictureRectangle, documentRectangle);
  414.     
  415.     return(noErr);
  416.     
  417. } // PICTGetDocumentRect
  418.  
  419. // --------------------------------------------------------------------------------------------------------------
  420.  
  421. static OSErr    PICTCloseWindow(WindowRef pWindow, WindowDataPtr pData)
  422. {
  423. #pragma unused (pWindow)
  424.  
  425.     DisposeHandle( (Handle) (((PICTDataPtr)pData)->cacheHandle));
  426.     
  427.     return(noErr);
  428.     
  429. } // PICTCloseWindow
  430.  
  431. // --------------------------------------------------------------------------------------------------------------
  432.  
  433. static OSErr    PICTContentClick(WindowRef pWindow, WindowDataPtr pData, EventRecord *pEvent)
  434. {
  435.     OSErr    anErr = noErr;
  436.     Rect    selectionRect = ((PICTDataPtr)pData)->selectionRectangle;
  437.     Point    clickPoint = pEvent->where;
  438.     
  439.     GlobalToLocal(&clickPoint);
  440.     OffsetRect(&selectionRect, -GetControlValue(pData->hScroll), -GetControlValue(pData->vScroll));
  441.     if ( (gMachineInfo.haveDragMgr) && (PtInRect(clickPoint, &selectionRect)) )
  442.         {
  443.         DragAndDropArea(pWindow, pData, pEvent, 
  444.                             &selectionRect);
  445.         }
  446.     else
  447.         {
  448.         anErr = SelectContents(pWindow, pData, pEvent, 
  449.                     &((PICTDataPtr)pData)->selectionRectangle, &((PICTDataPtr)pData)->pictureRectangle, 
  450.                     &((PICTDataPtr)pData)->patternPhase);
  451.         }
  452.     
  453.     return(anErr);
  454.     
  455. } // PICTContentClick
  456.  
  457. // --------------------------------------------------------------------------------------------------------------
  458.  
  459. static OSErr    PICTAdjustCursor(WindowRef pWindow, WindowDataPtr pData, Point * localMouse, Rect * globalRect)
  460. {
  461. #pragma unused (pWindow, globalRect)
  462.  
  463.     OSErr            anErr = noErr;
  464.     CursHandle        theCross;
  465.     Rect            selectionRect = ((PICTDataPtr)pData)->selectionRectangle;
  466.     
  467.     OffsetRect(&selectionRect, -GetControlValue(pData->hScroll), -GetControlValue(pData->vScroll));
  468.     if (!PtInRect(*localMouse, &selectionRect) )
  469.         {
  470.         theCross = GetCursor(crossCursor);
  471.         if (theCross)
  472.             {
  473.             char    oldState;
  474.             
  475.             oldState = HGetState((Handle) theCross);
  476.             HLock((Handle) theCross);
  477.             SetCursor(*theCross);
  478.             HSetState((Handle) theCross, oldState);
  479.             anErr = eActionAlreadyHandled;
  480.             }
  481.         }    
  482.         
  483.     return(anErr);
  484.     
  485. } // PICTAdjustCursor
  486.  
  487. // --------------------------------------------------------------------------------------------------------------
  488.  
  489. static OSErr    PICTDragAddFlavors(WindowRef pWindow, WindowDataPtr pData, DragReference theDragRef)
  490. {
  491. #pragma unused (pWindow)
  492.  
  493.     OSErr    anErr = noErr;
  494.     
  495.     SetDragSendProc(theDragRef, gPICTSendDataProc, nil);
  496.     AddDragItemFlavor(theDragRef, (unsigned long)pData, 'PICT', nil, 0, 0);
  497.     
  498.     return(anErr);
  499.     
  500. } // PICTDragAddFlavors
  501.  
  502. // --------------------------------------------------------------------------------------------------------------
  503.  
  504. static OSErr    PICTGetBalloon(WindowRef pWindow, WindowDataPtr pData, 
  505.         Point *localMouse, short * returnedBalloonIndex, Rect *returnedRectangle)
  506. {
  507. #pragma unused (pWindow, pData)
  508.  
  509.     Rect    tempRect = ((PICTDataPtr)pData)->selectionRectangle;
  510.     
  511.     // assume generic content
  512.     *returnedBalloonIndex = iHelpPictContent;
  513.     
  514.     // see if we are within the selection
  515.     OffsetRect(&tempRect, -GetControlValue(pData->hScroll), -GetControlValue(pData->vScroll) );
  516.     SectRect(&tempRect, &pData->contentRect, &tempRect);
  517.     
  518.     if (PtInRect(*localMouse, &tempRect))
  519.         {
  520.         *returnedRectangle        = tempRect;
  521.         *returnedBalloonIndex     = iHelpPictSelection;
  522.         }
  523.         
  524.     return(noErr);
  525.     
  526. } // PICTGetBalloon
  527.  
  528. // --------------------------------------------------------------------------------------------------------------
  529.  
  530. static OSErr    PICTPrintPage(WindowRef pWindow, WindowDataPtr pData,
  531.                     Rect * pageRect, long *pageNum)
  532. {
  533. #pragma unused (pWindow)
  534.  
  535.     OSErr    anErr = noErr;
  536.     short    pagesWide, pagesHigh;
  537.     Rect    pictureRect = ((PICTDataPtr)pData)->pictureRectangle;
  538.     Point    offset;
  539.     Rect    localPageRect = *pageRect;
  540.     
  541.     // calculate how many physical pages will be required to print this PICT
  542.     if (EqualRect(&pictureRect, &localPageRect))
  543.         pagesWide = pagesHigh = 1;
  544.     else
  545.         {
  546.         pagesWide = (pictureRect.right - pictureRect.left) / (localPageRect.right - localPageRect.left) + 1;
  547.         pagesHigh = (pictureRect.bottom - pictureRect.top) / (localPageRect.bottom - localPageRect.top) + 1;
  548.         }
  549.                     
  550.     // compute the offset in # of pages
  551.     offset.h = ((*pageNum - 1) % pagesWide);
  552.     offset.v = ((*pageNum - 1) / pagesWide);
  553.  
  554.     // compute the pixel offset for this page
  555.     offset.h *= localPageRect.right - localPageRect.left;
  556.     offset.v *= localPageRect.bottom - localPageRect.top;
  557.     
  558.     anErr = DiskPictureDraw( pData, true, &localPageRect, &offset);
  559.     
  560.     // tell it to stop printing when we reach the end
  561.     if (*pageNum >= (pagesWide*pagesHigh))
  562.         *pageNum = -1;
  563.     
  564.     return(anErr);
  565.     
  566. } // PICTPrintPage
  567.  
  568. // --------------------------------------------------------------------------------------------------------------
  569.  
  570. static OSErr    PICTAdjustMenus(WindowRef pWindow, WindowDataPtr pData)
  571. {
  572. #pragma unused (pWindow)
  573.  
  574.     OSErr anErr = noErr;
  575.     
  576.     if (!EmptyRect(&((PICTDataPtr)pData)->selectionRectangle))
  577.         EnableCommand(cCopy);
  578.  
  579.     if     (EqualRect(&((PICTDataPtr)pData)->pictureRectangle, &((PICTDataPtr)pData)->selectionRectangle))
  580.         ChangeCommandName(cSelectAll, kMiscStrings, iSelectNoneCommand);
  581.     else
  582.         ChangeCommandName(cSelectAll, kMiscStrings, iSelectAllCommand);
  583.     EnableCommand(cSelectAll);
  584.     
  585.     return(anErr);
  586.     
  587. } // PICTAdjustMenus
  588.  
  589. // --------------------------------------------------------------------------------------------------------------
  590.  
  591. static OSErr    PICTCommand(WindowRef pWindow, WindowDataPtr pData, short commandID, long menuResult)
  592. {
  593. #pragma unused (pWindow, menuResult)
  594.  
  595.     OSErr    anErr = noErr;
  596.     
  597.     switch (commandID)
  598.         {
  599.         case cCopy:
  600.             anErr = CopyGWorld(pData);
  601.             break;
  602.         
  603.         case cSelectAll:
  604.             // erase the old selection
  605.             DrawSelection(pData, &((PICTDataPtr)pData)->selectionRectangle, &((PICTDataPtr)pData)->patternPhase, false);
  606.             
  607.             if     (EqualRect(&((PICTDataPtr)pData)->pictureRectangle, &((PICTDataPtr)pData)->selectionRectangle))
  608.                 {
  609.                 ((PICTDataPtr)pData)->selectionRectangle.top = 0;
  610.                 ((PICTDataPtr)pData)->selectionRectangle.left = 0;
  611.                 ((PICTDataPtr)pData)->selectionRectangle.bottom = 0;
  612.                 ((PICTDataPtr)pData)->selectionRectangle.right = 0;
  613.                 }
  614.             else
  615.                 {
  616.                 ((PICTDataPtr)pData)->selectionRectangle = ((PICTDataPtr)pData)->pictureRectangle;
  617.                 }
  618.                 
  619.             // draw the new selection
  620.             DrawSelection(pData, &((PICTDataPtr)pData)->selectionRectangle, &((PICTDataPtr)pData)->patternPhase, true);
  621.             break;
  622.         }
  623.     
  624.     return(anErr);
  625.     
  626. } // PICTCommand
  627.  
  628. // --------------------------------------------------------------------------------------------------------------
  629.  
  630. static long PICTCalculateIdleTime(WindowRef pWindow, WindowDataPtr pData)
  631. {
  632. #pragma unused (pWindow)
  633.  
  634.     if (!EmptyRect( &((PICTDataPtr)pData)->selectionRectangle))
  635.         return(0);
  636.     else
  637.         return(kMaxWaitTime);
  638.         
  639. } // PICTCalculateIdleTime
  640.  
  641. // --------------------------------------------------------------------------------------------------------------
  642.  
  643. static Boolean    PICTFilterEvent(WindowRef pWindow, WindowDataPtr pData, EventRecord *pEvent)
  644. {
  645.     if     (
  646.         (!gMachineInfo.amInBackground) &&
  647.         (pEvent->what == nullEvent) &&
  648.         (pWindow == FrontWindow()) &&
  649.         (EmptyRgn( ((WindowPeek)pWindow)->updateRgn)) &&
  650.         (MOVESELECTION(pEvent->when) )
  651.         )
  652.         {
  653.         // erase the old
  654.         DrawSelection(pData, &((PICTDataPtr)pData)->selectionRectangle, &((PICTDataPtr)pData)->patternPhase, false);
  655.         
  656.         // draw the new, moving onto the next pattern
  657.         DrawSelection(pData, &((PICTDataPtr)pData)->selectionRectangle, &((PICTDataPtr)pData)->patternPhase, true);
  658.         }
  659.         
  660.     return(false);
  661.     
  662. } // PICTFilterEvent
  663.  
  664. // --------------------------------------------------------------------------------------------------------------
  665.  
  666. static OSErr    PICTMakeWindow(WindowRef pWindow, WindowDataPtr pData)
  667. {
  668. #pragma unused (pWindow)
  669.  
  670.     Size    availableRAM;
  671.     long    amountInFile;
  672.     OSErr    anErr = noErr;
  673.     
  674.     pData->pUpdateWindow         = (UpdateWindowProc)        PICTUpdateWindow;
  675.     pData->pGetDocumentRect     = (GetDocumentRectProc)        PICTGetDocumentRect;
  676.     pData->pCloseWindow         = (CloseWindowProc)            PICTCloseWindow;
  677.     pData->pContentClick         = (ContentClickProc)        PICTContentClick;
  678.     pData->pAdjustCursor         = (AdjustCursorProc)        PICTAdjustCursor;
  679.     pData->pGetBalloon             = (GetBalloonProc)            PICTGetBalloon;
  680.     pData->pAdjustMenus         = (AdjustMenusProc)            PICTAdjustMenus;
  681.     pData->pPrintPage             = (PrintPageProc)            PICTPrintPage;
  682.     pData->pCommand                 = (CommandProc)                PICTCommand;
  683.     pData->pFilterEvent             = (FilterEventProc)            PICTFilterEvent;
  684.     pData->pCalculateIdleTime    = (CalculateIdleTimeProc)    PICTCalculateIdleTime;
  685.     pData->pDragAddFlavors        = (DragAddFlavorsProc)        PICTDragAddFlavors;
  686.     
  687.     pData->hasGrow                = true;
  688.     pData->hScrollAmount        = 10;
  689.     pData->vScrollAmount        = 10;
  690.     
  691.     // Calculate amount of available RAM for cache
  692.     {
  693.     Size grow;
  694.     availableRAM = MaxMem(&grow);
  695.     }
  696.     
  697.     // Take half of it
  698.     availableRAM >>= 1;
  699.     
  700.     // if too big, make it just big enough
  701.     GetEOF(pData->dataRefNum, &amountInFile);
  702.     amountInFile -= 512;
  703.     
  704.     if (amountInFile < sizeof(Picture))
  705.         anErr = eErrorWhileDrawing;
  706.     else
  707.         {
  708.         if (availableRAM > amountInFile)
  709.             {
  710.             Handle    theHandle = NewHandle(amountInFile);
  711.             
  712.             if (theHandle)
  713.                 {
  714.                 SetFPos(pData->dataRefNum, fsFromStart, 512);
  715.                 FSRead(pData->dataRefNum, &amountInFile, *theHandle);
  716.                 
  717.                 ((PICTDataPtr)pData)->cacheHandle = (PicHandle)theHandle;
  718.                 }
  719.             }
  720.             
  721.         // initialize the rectangle to be valid
  722.         {
  723.         Rect    pictureRect;
  724.  
  725.         DiskPictureDraw( pData, false, &((PICTDataPtr)pData)->pictureRectangle, nil);
  726.     
  727.         pictureRect = ((PICTDataPtr)pData)->pictureRectangle;
  728.         if ((pData->contentRect.right > pictureRect.right) && (pictureRect.right > 0))
  729.             pData->contentRect.right = pictureRect.right;
  730.         if ((pData->contentRect.bottom > pictureRect.bottom) && (pictureRect.bottom > 0))
  731.             pData->contentRect.bottom = pictureRect.bottom;
  732.         }
  733.         }
  734.     
  735.     return(anErr);
  736.     
  737. } // PICTMakeWindow
  738.  
  739.  
  740. // --------------------------------------------------------------------------------------------------------------
  741.  
  742. OSErr    PICTPreflightWindow(PreflightPtr pPreflightData)
  743. {
  744.     pPreflightData->wantHScroll            = true;
  745.     pPreflightData->wantVScroll            = true;
  746.     
  747.     pPreflightData->continueWithOpen     = true;
  748.     pPreflightData->makeProcPtr         = PICTMakeWindow;
  749.     
  750.     pPreflightData->storageSize = sizeof(PICTDataRecord);
  751.     
  752.     return(noErr);
  753.     
  754. } // PICTPreflightWindow
  755.  
  756. // --------------------------------------------------------------------------------------------------------------
  757.  
  758. void PICTGetFileTypes(OSType * pFileTypes, OSType * pDocumentTypes, short * numTypes)
  759. {
  760.     pFileTypes[*numTypes]         = 'PICT';
  761.     pDocumentTypes[*numTypes]     = kPICTWindow;
  762.     (*numTypes)++;
  763.     
  764. } // PICTGetFileTypes
  765.